﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ViewModel;
using DataLayer;
using Helper;
namespace Service
{
    public class Issues
    {
        public static void GetAllIssues(ref List<Issue> Open, ref List<Issue> InProgress, ref List<Issue> Closed, ref List<Issue> Rejected, int count = 10)
        {
            try
            {
                using (iTrackerEntities DB = new iTrackerEntities())
                {
                    Open = (from i in DB.issues
                            join a in DB.assignments on i.id equals a.issue_id
                            join s in DB.shops on a.shop_id equals s.id
                            where (i.status_id == 1 || i.status_id == 2)
                            && a.is_active
                            && a.shop_id == ((int)ActiveSession.User.Role == 1 ? a.shop_id.Value : ActiveSession.User.Shop.ID)
                             && i.date_start <= DateTime.Today
                            select new Issue()
                            {
                                ID = i.id,
                                Name = i.name,
                                Description = i.description,
                                Priority = (Priority)i.priority_id,
                                Status = (Status)i.status_id,
                                DateCreated = i.date_created,
                                DateStart = i.date_start,
                                DateEnd = i.date_end,
                                Assignee = new List<Shop>() { new Shop() { ID = s.id, Name = s.name, UDF1 = s.udf1 } },
                                DateCompleted = a.date_updated,
                                IsRequest = i.is_request
                            })
                            .Take(count)
                         .ToList();

                    InProgress = (from i in DB.issues
                                  join a in DB.assignments on i.id equals a.issue_id
                                  join s in DB.shops on a.shop_id equals s.id
                                  where (i.status_id == 3)
                                  && a.is_active
                                  && a.shop_id == ((int)ActiveSession.User.Role == 1 ? a.shop_id.Value : ActiveSession.User.Shop.ID)
                                   && i.date_start <= DateTime.Today
                                  select new Issue()
                                  {
                                      ID = i.id,
                                      Name = i.name,
                                      Description = i.description,
                                      Priority = (Priority)i.priority_id,
                                      Status = (Status)i.status_id,
                                      DateCreated = i.date_created,
                                      DateStart = i.date_start,
                                      DateEnd = i.date_end,
                                      Assignee = new List<Shop>() { new Shop() { ID = s.id, Name = s.name, UDF1 = s.udf1 } },
                                      DateCompleted = a.date_updated,
                                      IsRequest = i.is_request
                                  })
                                  .Take(count)
                         .ToList();

                    Closed = (from i in DB.issues
                              join a in DB.assignments on i.id equals a.issue_id
                              join s in DB.shops on a.shop_id equals s.id
                              where (i.status_id == 4)
                              && a.is_active
                              && a.shop_id == ((int)ActiveSession.User.Role == 1 ? a.shop_id.Value : ActiveSession.User.Shop.ID)
                               && i.date_start <= DateTime.Today
                              select new Issue()
                              {
                                  ID = i.id,
                                  Name = i.name,
                                  Description = i.description,
                                  Priority = (Priority)i.priority_id,
                                  Status = (Status)i.status_id,
                                  DateCreated = i.date_created,
                                  DateStart = i.date_start,
                                  DateEnd = i.date_end,
                                  Assignee = new List<Shop>() { new Shop() { ID = s.id, Name = s.name, UDF1 = s.udf1 } },
                                  DateCompleted = a.date_updated,
                                  IsRequest = i.is_request
                              })
                              .Take(count)
                         .ToList();

                    Rejected = (from i in DB.issues
                                join a in DB.assignments on i.id equals a.issue_id
                                join s in DB.shops on a.shop_id equals s.id
                                where (i.status_id == 5)
                                && a.is_active
                                && a.shop_id == ((int)ActiveSession.User.Role == 1 ? a.shop_id.Value : ActiveSession.User.Shop.ID)
                                 && i.date_start <= DateTime.Today
                                select new Issue()
                                {
                                    ID = i.id,
                                    Name = i.name,
                                    Description = i.description,
                                    Priority = (Priority)i.priority_id,
                                    Status = (Status)i.status_id,
                                    DateCreated = i.date_created,
                                    DateStart = i.date_start,
                                    DateEnd = i.date_end,
                                    Assignee = new List<Shop>() { new Shop() { ID = s.id, Name = s.name, UDF1 = s.udf1 } },
                                    DateCompleted = a.date_updated,
                                    IsRequest = i.is_request
                                })
                                .Take(count)
                         .ToList();
                }
            }
            catch (Exception ex)
            {
                Helper.ErrorLogger.WriteLog("GetAllIssues", ex);
                throw;
            }
            

        }

        public static Issue GetIssueDetails(int id)
        {
            Issue item = new Issue();
            List<Shop> assignee = new List<Shop>();
            List<Comment> comments = new List<Comment>();
            try
            {
                using (iTrackerEntities DB = new iTrackerEntities())
                {
                    item = (from i in DB.issues
                            join a in DB.assignments on i.id equals a.issue_id
                            join s in DB.shops on a.shop_id equals s.id
                            join ar in DB.areas on s.area_code equals ar.code into ao
                            from ar in ao.DefaultIfEmpty()
                            join g in DB.groups on s.group_id equals g.id into go
                            from g in go.DefaultIfEmpty()
                            where i.id == id
                            select new Issue()
                            {
                                ID = i.id,
                                Name = i.name,
                                Description = i.description,
                                Priority = (Priority)i.priority_id,
                                Status = (Status)i.status_id,
                                DateCreated = i.date_created,
                                DateStart = i.date_start,
                                DateEnd = i.date_end,
                                DateCompleted = a.date_updated,
                                IsRequest = i.is_request,
                                UDF1 = i.udf1
                            }).FirstOrDefault();

                    assignee = (from a in DB.assignments
                                join s in DB.shops on a.shop_id equals s.id
                                join ar in DB.areas on s.area_code equals ar.code into ao
                                from ar in ao.DefaultIfEmpty()
                                join g in DB.groups on s.group_id equals g.id into go
                                from g in go.DefaultIfEmpty()
                                where a.issue_id == id
                                select new Shop()
                                {
                                    ID = s.id,
                                    Name = s.name,
                                    Department = s.department,
                                    Area = new Area() { ID = ar.id, Name = ar.name, Description = ar.description, AreaCode = ar.code },
                                    Group = new Group() { ID = g.id, Name = g.name, Description = g.description },
                                    UDF1 = s.udf1,
                                    UDF2 = s.udf2,
                                    UDF3 = s.udf3,
                                    UDF4 = s.udf4,
                                    UDF5 = s.udf5
                                }).ToList();
                    comments = (from c in DB.comments
                                join i in DB.issues on c.issue_id equals i.id
                                join u in DB.users on c.comment_by equals u.id
                                where c.is_visible && i.id == id
                                orderby c.commented_on descending
                                select new Comment()
                                {
                                    ID = c.id,
                                    CreatedByID = u.id,
                                    CreatedByText = u.username,
                                    IssueID = i.id,
                                    DateCreated = c.commented_on,
                                    Content = c.content
                                }).ToList();

                }
            }
            catch (Exception ex)
            {
                Helper.ErrorLogger.WriteLog("GetIssueDetails", ex);
                throw;
            }
            
            item.Assignee = assignee;
            item.Comments = comments;
            return item;
        }

        public static int PostComment(int issueID, string comment)
        {
            int chk = 0;
            try
            {
                using (iTrackerEntities DB = new iTrackerEntities())
                {
                    comment obj = new comment()
                    {
                        issue_id = issueID,
                        content = comment,
                        commented_on = DateTime.Now,
                        comment_by = ActiveSession.User.ID,
                        is_visible = true
                    };
                    DB.comments.Add(obj);
                    chk = DB.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Helper.ErrorLogger.WriteLog("PostComment", ex);
                throw;
            }            
            return chk;
        }

        public static int UpdateIssueValue(int issueID, Status st, int value)
        {
            int chk = 0;
            try
            {
                using (iTrackerEntities DB = new iTrackerEntities())
                {
                    issue obj = DB.issues.Where(x => x.id == issueID).FirstOrDefault();
                    obj.status_id = (int)st;
                    obj.udf1 = value;
                    assignment asgn = DB.assignments.Where(x => x.issue_id == issueID).FirstOrDefault();
                    if (st == Status.Closed)
                    {
                        asgn.date_updated = DateTime.Now;
                        //asgn.is_active
                    }
                    else
                    {
                        asgn.date_updated = null;
                    }

                    chk = DB.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                Helper.ErrorLogger.WriteLog("UpdateIssueValue", ex);
                throw;
            }
            
            return chk;
        }

        public static List<Issue> Search(string term, Filter doFilter)
        {
            //check if admin
            if (ActiveSession.User.Role != Role.Admininstrator)
            {
                doFilter.Shops = new List<int>();
                doFilter.Shops.Add(ActiveSession.User.ShopID);
            }
            int id = 0;
            Int32.TryParse(term, out id);

            List<Issue> issues = new List<Issue>();
            try
            {
                using (iTrackerEntities DB = new iTrackerEntities())
                {
                    issues = (from i in DB.issues
                              join a in DB.assignments on i.id equals a.issue_id
                              join s in doFilter.Shops != null ? DB.shops.Where(x => doFilter.Shops.Contains(x.id)) : DB.shops on a.shop_id equals s.id
                              where
                               a.is_active
                                && i.status_id == (doFilter.Status.HasValue ? (int)doFilter.Status.Value : i.status_id)
                                && i.priority_id == (doFilter.Priority.HasValue ? (int)doFilter.Priority.Value : i.priority_id)
                                && i.date_start >= (doFilter.From.HasValue ? doFilter.From.Value : i.date_start)
                                && i.date_end <= (doFilter.To.HasValue ? doFilter.To.Value : i.date_end)
                                  //&& i.name.Contains(term)
                                && (i.id == id || i.name.Contains(term))
                              select new Issue()
                              {
                                  ID = i.id,
                                  Name = i.name,
                                  Description = i.description,
                                  Priority = (Priority)i.priority_id,
                                  Status = (Status)i.status_id,
                                  DateCreated = i.date_created,
                                  DateStart = i.date_start,
                                  DateEnd = i.date_end,
                                  Assignee = new List<Shop>() { new Shop() { ID = s.id, Name = s.name, UDF1 = s.udf1 } },
                                  DateCompleted = a.date_updated,
                                  IsRequest = i.is_request
                              })
                         .ToList();

                }
            }
            catch (Exception ex)
            {
                Helper.ErrorLogger.WriteLog("Search", ex);
                throw;
            }
            
            return issues;
        }
    }
}
